﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Bson.Serialization.Attributes;

namespace YmtAuth.Domain.Model.BlacklistUser
{
    public class YmatouBlacklistUser : Entity<string>
    {

        [BsonElement("lTime")]
        public DateTime LockdTime { get; set; }
        [BsonElement("cTime")]
        public DateTime CreateTime { get; set; }
        public int Count { get; set; }
        [BsonElement("lIps")]
        [BsonIgnoreIfNull]
        //[BsonRepresentation(MongoDB.Bson.BsonType.Array)]
        public HashSet<string> LoginIpArray { get; set; }

        public YmatouBlacklistUser(string loginId, string loginIp, DateTime? lockdTime = null)
        {
            this.Id = loginId.ToLower();
            this.LockdTime = lockdTime ?? DateTime.Now.Add(LockdTimeSpan);
            this.CreateTime = DateTime.Now;
            this.Count = 1;
            if (!string.IsNullOrEmpty(loginIp))
                this.LoginIpArray = new HashSet<string>(new[] { loginIp });
        }
        public void IncrementCount()
        {
            var _c = this.Count;


            this.Count = System.Threading.Interlocked.Increment(ref _c); ;
        }
        public void RefreshLockTime()
        {
            this.LockdTime = DateTime.Now.Add(LockdTimeSpan);
        }
        public void AppendLoginIp(string loginIp)
        {
            if (string.IsNullOrEmpty(loginIp)) return;
            if (this.LoginIpArray == null)
                this.LoginIpArray = new HashSet<string>(new[] { loginIp });
            else
            {
                if (this.LoginIpArray.Count < 10)
                    this.LoginIpArray.Add(loginIp);
                else
                {
                    var _subListIp = this.LoginIpArray.Take(8);
                    var _tmpHashset = new HashSet<string>(_subListIp);
                    _tmpHashset.Add(loginIp);
                    this.LoginIpArray = _tmpHashset;
                }
            }
        }
        public static bool IsBlacklistUser(long loginfailcount)
        {
            var cfg = ConfigurationManager.AppSettings["backlistloginfail"];
            int defVal = 0;
            if (int.TryParse(cfg, out defVal))
            {
                return (int)loginfailcount >= defVal;
            }
            return false;
        }

        public bool IsNotAllowLogin()
        {
            return this.LockdTime.ToLocalTime() >= DateTime.Now;
        }

        public static bool Enable
        {
            get { return ConfigurationManager.AppSettings["blacklistuser"] == "1"; }
        }

        public string ResponseMsg
        {
            get
            {
                var cfgMsg = ConfigurationManager.AppSettings["blacklistmessage"];
                var msg = LockdTimeSpan.Hours > 0 ? LockdTimeSpan.ToString("h'小时 'm'分 's'秒'") : LockdTimeSpan.TotalMinutes + "分钟";
                return string.Format(cfgMsg, msg);
            }
        }

        public static TimeSpan LockdTimeSpan
        {
            get
            {
                var time = ConfigurationManager.AppSettings["blacklistuserlocktime"];
                if (string.IsNullOrEmpty(time)) return TimeSpan.FromMinutes(5);
                TimeSpan ts = TimeSpan.FromMinutes(5);
                TimeSpan.TryParse(time, out ts);
                return ts;
            }
        }
        protected YmatouBlacklistUser()
        {
        }

        protected override IEnumerable<object> CompareValues()
        {
            yield return this.Id;
        }
    }
}
